<template>
  <div ref="dynamic-chart" style="width: 1000px; height: 500px"></div>
</template>

<script lang="ts">
import { PropType } from 'vue';
import * as echarts from 'echarts';
import DataFormatterMixin from '@/components/Mixins/DataFormatterMixin';

export default {
  mixins: [DataFormatterMixin],
  props: {
    sensorsName: {
      type: String as PropType<string>,
      required: true,
    },
    type: {
      type: String as PropType<string>,
      required: true,
    },
    memberId: {
      type: String as PropType<string>,
      required: true,
    },
    units: {
      type: String as PropType<string>,
      required: true,
    },
    lowerCaution: {
      required: true,
    },
    upperCaution: {
      required: true,
    },
    lowerCritical: {
      required: true,
    },
    upperCritical: {
      required: true,
    },
    currentValue: {
      required: true,
    },
  },
  data() {
    return {
      chart: null,
      option: null,
      currentTime: 0,
      currentDataObj: {
        accData: this.currentValue,
        accCount: 1,
        useTag: 0,
      },
      WebSocket: null,
      notUsed: 1,
      used: 0,
      defaultInterval: 5,
    };
  },
  mounted() {
    this.chart = echarts.init(this.$refs['dynamic-chart'] as HTMLElement);
    this.setupChart();
    this.linkSocket();
    setInterval(this.fetchData, 5000);
    this.sendChartBoxToParent();
  },
  beforeDestroy() {
    this.WebSocket.close();
  },
  methods: {
    setupChart() {
      let lowerCritical = this.lowerCritical ? this.lowerCritical : 0;
      let upperCritical = this.upperCritical ? this.upperCritical : 0;
      let lowerCaution = this.lowerCaution ? this.lowerCaution : 0;
      let upperCaution = this.upperCaution ? this.upperCaution : 0;
      let currentValue = this.currentValue ? this.currentValue : 0;
      let ymax = Math.ceil(
        Math.max(
          currentValue,
          lowerCritical,
          upperCritical,
          lowerCaution,
          upperCaution
        ) * 1.1
      );
      let ymin = Math.floor(
        Math.min(
          currentValue,
          lowerCritical,
          upperCritical,
          lowerCaution,
          upperCaution
        ) * 0.9
      );
      this.option = {
        legend: {
          data: [this.sensorsName],
          right: 10,
          top: 10,
        },
        tooltip: {
          trigger: 'axis',
        },
        xAxis: {
          type: 'category',
          data: [],
        },
        yAxis: {
          type: 'value',
          name: 'units（' + this.unitFormatter(this.units) + '）',
          max: ymax,
          min: ymin,
        },
        series: [
          {
            name: this.sensorsName,
            type: 'line',
            data: [],
            smooth: true,
            markLine: {
              animation: false,
              data: [
                {
                  yAxis: this.lowerCritical ? this.lowerCritical : {},
                  lineStyle: {
                    color: 'red',
                  },
                  label: {
                    formatter: 'Lower Critical',
                  },
                },
                {
                  yAxis: this.upperCritical ? this.upperCritical : {},
                  lineStyle: {
                    color: 'red',
                  },
                  label: {
                    formatter: 'Upper Critical',
                  },
                },
                {
                  yAxis: this.upperCaution ? this.upperCaution : {},
                  lineStyle: {
                    color: '#EBEF18',
                  },
                  label: {
                    formatter: 'Upper Caution',
                  },
                },
                {
                  yAxis: this.lowerCaution ? this.lowerCaution : {},
                  lineStyle: {
                    color: '#EBEF18',
                  },
                  label: {
                    formatter: 'Lower Caution',
                  },
                },
              ],
            },
          },
        ],
      };
      this.chart.setOption(this.option, true);
    },

    linkSocket() {
      let ws: WebSocket;
      const data = {
        paths: [
          '/xyz/openbmc_project/sensors/' + this.type + '/' + this.memberId,
        ],
        interfaces: ['xyz.openbmc_project.Sensor.Value'],
      };
      const socketDisabled =
        process.env.VUE_APP_SUBSCRIBE_SOCKET_DISABLED === 'true' ? true : false;
      if (socketDisabled) return;
      const token = this.$store.getters['authentication/token'];
      ws = new WebSocket(`wss://${window.location.host}/subscribe`, [token]);
      this.WebSocket = ws;
      ws.onopen = () => {
        ws.send(JSON.stringify(data));
      };
      ws.onerror = (event) => {
        console.error(event);
      };
      ws.onmessage = (event) => {
        const data = JSON.parse(event.data);
        if (this.currentDataObj.useTag === this.used) {
          this.currentDataObj.accData = 0;
          this.currentDataObj.accCount = 0;
          this.currentDataObj.useTag = this.notUsed;
        }
        this.currentDataObj.accData += data.properties.Value;
        this.currentDataObj.accCount++;
      };
    },

    fetchData() {
      let currentData =
        this.currentDataObj.accData / this.currentDataObj.accCount;
      this.currentDataObj.accData = currentData;
      this.currentDataObj.accCount = 1;
      this.currentDataObj.useTag = this.used;
      this.option.series[0].data.push(currentData);
      this.currentTime = this.currentTime + this.defaultInterval;
      this.option.xAxis.data.push(this.currentTime);
      this.option.yAxis.max = Math.max(
        Math.ceil(currentData),
        this.option.yAxis.max
      );
      this.option.yAxis.min = Math.min(
        Math.floor(currentData),
        this.option.yAxis.min
      );
      if (this.option.series[0].data.length > 60) {
        this.option.xAxis.data.shift();
        this.option.series[0].data.shift();
      }
      this.chart.setOption(this.option, true);
    },
    sendChartBoxToParent() {
      this.$emit('send-chart-box', this.chart, this.sensorsName);
    },
  },
};
</script>
